#!/usr/bin/env python
# -*- encoding: utf8 -*-

import unittest2 as unittest

from lxml import etree
import mox

from blogger import import_posts


__autor__ = 'fcamel'


class GetCategoryTest(unittest.TestCase):
    def setUp(self):
        self.ns = 'http://www.w3.org/2005/Atom'

    def testEmpty(self):
        entry = etree.fromstring('<entry xmlns="%s"></entry>' % self.ns)
        actual = import_posts.get_categories(entry, self.ns)
        self.assertListEqual([], actual)

    def testNewFormat(self):
        '''
        It should extract categories that don't belong to Google Reader.
        '''
        xml = '''<entry xmlns="%s">
                    <category term="user/09119390518375652130/label/Friends"
                              scheme="http://www.google.com/reader/"
                              label="Friends"/>
                    <category term="Python" scheme="http://fcamel.twbbs.org"/>
                    <category term="Ruby" scheme="http://fcamel.twbbs.org"/>
                 </entry>''' % self.ns

        entry = etree.fromstring(xml)
        actual = import_posts.get_categories(entry, self.ns)
        self.assertListEqual(['Python', 'Ruby'], actual)

    def testOldFormat(self):
        '''
        It should extract categories that don't have the attribute scheme.
        '''
        xml = '''<entry xmlns="%s">
                    <category term="user/09119390518375652130/label/Friends"
                              scheme="http://www.google.com/reader/"
                              label="Friends"/>
                    <category term="Python"/>
                    <category term="Ruby"/>
                 </entry>''' % self.ns

        entry = etree.fromstring(xml)
        actual = import_posts.get_categories(entry, self.ns)
        self.assertListEqual(['Python', 'Ruby'], actual)


class ProcessTest(unittest.TestCase):
    def setUp(self):
        self.m = mox.Mox()
        self.blog_id = 123
        self.begin = 34
        self.posts = range(1, 51)

        self.client = self.m.CreateMock(import_posts.MyBloggerClient)
        self.recorder = self.m.CreateMock(import_posts.FailedPointRecorder)

    def testNormal(self):
        # Prepare fixtures.
        for i in self.posts:
            self.client.submit(i, self.blog_id)

        self.recorder.clean()

        self.m.ReplayAll()

        # Run.
        import_posts.process(self.posts, 1, self.client,
                             self.blog_id, self.recorder)

        # Verify.
        self.m.VerifyAll()

    def testBegin(self):
        # Prepare fixtures.
        for i in range(self.begin, 51):
            self.client.submit(i, self.blog_id)

        self.recorder.clean()

        self.m.ReplayAll()

        # Run.
        import_posts.process(self.posts, self.begin, self.client,
                             self.blog_id, self.recorder)

        # Verify.
        self.m.VerifyAll()

    def testWriteFailedPointWhenErrorHappens(self):
        # Prepare fixtures.
        self.client.submit(self.begin, self.blog_id)
        self.client.submit(self.begin + 1, self.blog_id)
        self.client.submit(self.begin + 2, self.blog_id).AndRaise(Exception(''))

        # the action of logging the failed point should happen.
        self.recorder.write_failed_point(self.begin + 2)

        self.m.ReplayAll()

        # Run.
        with self.assertRaises(Exception):
            import_posts.process(self.posts, self.begin, self.client,
                                 self.blog_id, self.recorder)

        # Verify.
        self.m.VerifyAll()


if __name__ == '__main__':
    unittest.main()
